using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace SpoonStream
{
	public class NetworkQueue<T>
	{
		private static Random _rand = new Random();
		
		private double _packetLoss = 0; // Persent
		private double _delayMin = 0; // Delay in ms
		private double _delayMax = 0; // Delay in ms
		
		public delegate void OnReceiveHandler(T item);

		public event OnReceiveHandler OnReceive;

		public void Enqueue(T item)
		{
			// Packetloss
			if (_rand.NextDouble() >= _packetLoss)
			{
				double delay = (_rand.NextDouble()*(_delayMax - _delayMin)) + _delayMin;
				ThreadPool.QueueUserWorkItem(new WaitCallback(Send), new SendItem<T>(delay, item));
			}
		}

		private void Send(object obj)
		{
			SendItem<T> item = (SendItem<T>) obj;
			Thread.Sleep((int)item.Delay);
			if (OnReceive != null) OnReceive(item.Item);
		}

		private class SendItem<T>
		{
			public double Delay;
			public T Item;

			public SendItem(double delay, T item)
			{
				Delay = delay;
				Item = item;
			}
		}
	}
}
